import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    count: 0,
    todos: [
      { id: 1, text: 'one', done: true },
      { id: 2, text: 'two', done: false }
    ]
  },
  // mutaion 必须是同步函数
  // 更改 Vuex 的 store 中的状态的唯一方法是提交 mutation
  mutations: {
    // 接受 state 作为第一个参数，也可以向 store.commit 传入额外的参数，即 mutaion 的载荷 Payload
    increment (state, payload) {
      state.count += payload.amount
    }
  },
  // Vuex 中允许我们在 store 中定义 getter(可以认为是store的计算属性)，就像计算属性一样，getter 的返回值会根据它的依赖被缓存起来，且只有当它的依赖值发生了改变才会被重新计算
  getters: {
    // getter 接受 state 作为其第一个参数
    doneTodos: state => {
      return state.todos.filter(todo => todo.done)
    },
    // getter 也可以接受其他 getter 作为第二个参数
    doneTodosCount: (state, getters) => {
      return getters.doneTodos.length
    },
    // 让 getter 返回一个函数，来实现给 getter 传参，在对 store 里面的数组进行查询时非常有用
    getTodosById: (state) => (id) => {
      return state.todos.find(todo => todo.id === id)
    }
  },
  // Action 类似于 mutation，不同在于： Action 提交的是 mutation，而不是直接变更状态;Action 可以包含任意异步操作
  actions: {
    // Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象，可以调用 context.commit 提交一个 mutation，或通过 context.state 和 context.getters 来获取 state 和 getters
    // increment (context) {
    //   context.commit('increment', {
    //     amount: 5
    //   })
    // },
    // 使用 参数解构来简化代码（特别是当我们需要调用 commit 很多次的时候）
    // 可以在 action 内部执行异步操作
    increment ({ commit }) {
      commit('increment', {
        amount: 5
      })
    }
  }
})

export default store